![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
chrono-node
Advanced tools
chrono-node is a natural language date parser in JavaScript. It can parse dates from various date formats and natural language text, making it useful for applications that need to understand and manipulate dates from user input.
Parsing Dates from Natural Language
This feature allows you to parse dates from natural language text. In this example, the text 'Let's meet on Tuesday' is parsed to a Date object representing the next Tuesday.
const chrono = require('chrono-node');
const result = chrono.parseDate('Let's meet on Tuesday');
console.log(result);
Parsing Dates with Specific Time
This feature allows you to parse dates that include specific times. The text 'The event is at 5 PM on 20th October' is parsed to a Date object representing the specified date and time.
const chrono = require('chrono-node');
const result = chrono.parseDate('The event is at 5 PM on 20th October');
console.log(result);
Parsing Relative Dates
This feature allows you to parse relative dates. The text '2 days from now' is parsed to a Date object representing the date two days from the current date.
const chrono = require('chrono-node');
const result = chrono.parseDate('2 days from now');
console.log(result);
Customizing Parsers
This feature allows you to customize the parsers used by chrono-node. In this example, a custom parser is created and used to parse the text 'next Friday'.
const chrono = require('chrono-node');
const customParser = new chrono.Chrono();
customParser.parsers.push(new chrono.Parser());
const result = customParser.parseDate('next Friday');
console.log(result);
date-fns is a modern JavaScript date utility library that provides comprehensive, yet simple, functions for working with dates. Unlike chrono-node, which focuses on natural language parsing, date-fns offers a wide range of date manipulation and formatting functions.
Moment.js is a widely-used library for parsing, validating, manipulating, and formatting dates. While it does not focus on natural language parsing like chrono-node, it provides extensive functionality for handling dates and times in JavaScript.
Luxon is a modern JavaScript library for working with dates and times, created by one of the Moment.js developers. It offers a more modern API and better support for internationalization compared to Moment.js, but like Moment.js, it does not specialize in natural language parsing.
A natural language date parser in Javascript, designed for extracting date information from any given text. (Java version is also available here)
Chrono supports most date and time formats, such as :
Just run:
$ npm i --save chrono-node
And start using chrono:
var chrono = require('chrono-node');
chrono.parseDate('An appointment on Sep 12-13');
Try using the community-made chrono-swift wrapper.
Simply pass a string to function chrono.parseDate
or chrono.parse
.
var chrono = require('chrono-node');
chrono.parseDate('An appointment on Sep 12-13');
// Fri Sep 12 2014 12:00:00 GMT-0500 (CDT)
chrono.parse('An appointment on Sep 12-13');
/* [ { index: 18,
text: 'Sep 12-13',
tags: { ENMonthNameMiddleEndianParser: true },
start:
{ knownValues: [Object],
impliedValues: [Object] },
end:
{ knownValues: [Object],
impliedValues: [Object] } } ] */
Today's "Friday" is different from last month's "Friday".
The meaning of the referenced dates depends on when they are mentioned.
Chrono lets you define a reference date using chrono.parse(text, ref)
and chrono.parseDate(text, ref)
.
chrono.parseDate('Friday', new Date(2012, 7, 23));
// Fri Aug 24 2012 12:00:00 GMT+0700 (ICT)
chrono.parseDate('Friday', new Date(2012, 7, 1));
// Fri Aug 03 2012 12:00:00 GMT+0700 (ICT)
forwardDate
(boolean) to assume the results should happen after the reference date (forward into the future)var referenceDate = new Date(2012, 7, 25);
// Sat Aug 25 2012 00:00:00 GMT+0900 -- The reference date was Saturday
chrono.parseDate('Friday', referenceDate);
// Fri Aug 24 2012 12:00:00 GMT+0900 (JST) -- The day before was Friday
chrono.parseDate('Friday', referenceDate, { forwardDate: true });
// Fri Aug 31 2012 12:00:00 GMT+0900 (JST) -- The following Friday
timezones
(Map) to override Chrono's default timezone abbriviation mapping. The value should be the timezone offset in minutes (between -720 to 720).chrono.parse('Friday at 2 pm IST', refDate, { timezones: { 'IST': 330 } })[0].start.get('timezoneOffset');
// 330 (IST – India Standard Time +0530)
chrono.parse('Friday at 2 pm IST', refDate, { timezones: {'IST': 60 } })[0].start.get('timezoneOffset');
// 60 (IST - Irish Standard Time +0100)
The function chrono.parse
returns detailed parsing results as objects of class chrono.ParsedResult
.
var results = chrono.parse('I have an appointment tomorrow from 10 to 11 AM');
results[0].index; // 15
results[0].text; // 'tomorrow from 10 to 11 AM'
results[0].ref; // Sat Dec 13 2014 21:50:14 GMT-0600 (CST)
results[0].start.date(); // Sun Dec 14 2014 10:00:00 GMT-0600 (CST)
results[0].end.date(); // Sun Dec 14 2014 11:00:00 GMT-0600 (CST)
start
The parsed date components as a ParsedComponents objectend
Similar to start
but can be null.index
The location within the input text of this resulttext
The text this result that appears in the inputref
The reference date of this resultA group of found date and time components (year, month, hour, etc). ParsedComponents objects consist of knownValues
and impliedValues
.
assign(component, value)
Set known value to the componentimply(component, value)
Set implied value to the componentget(component)
Get known or implied value for the componentisCertain(component)
return true if the value of the component is known.date()
Create a javascript Date// Remove the timezone offset of a parsed date and then create the Date object
var results = new chrono.parse('2016-03-08T01:16:07+02:00'); // Create new ParsedResult Object
results[0].start.assign('timezoneOffset', 0); // Change value in ParsedComponents Object 'start'
var d = results[0].start.date(); // Create a Date object
d.toString(); // 'Tue Mar 08 2016 01:16:07 GMT+0000 (GMT)'
Chrono comes with strict
mode that parse only formal date patterns.
// 'strict' mode
chrono.strict.parseDate('Today'); // null
chrono.strict.parseDate('Friday'); // null
chrono.strict.parseDate('2016-07-01'); // Fri Jul 01 2016 12:00:00 ...
chrono.strict.parseDate('Jul 01 2016'); // Fri Jul 01 2016 12:00:00 ...
// 'casual' mode (default)
chrono.parseDate('Today'); // Thu Jun 30 2016 12:00:00 ...
chrono.casual.parseDate('Friday'); // Fri Jul 01 2016 12:00:00 ...
chrono.casual.parseDate('2016-07-01'); // Fri Jul 01 2016 12:00:00 ...
chrono.casual.parseDate('Jul 01 2016'); // Fri Jul 01 2016 12:00:00 ...
By default, Chrono is configurated to parse different date formats from muliple languages out-off-box. However, by using predefined locale options, you can increase parsing accuracy.
Handling different date format for UK / US is a good example.
// default English (US)
chrono.parseDate('6/10/2018'); // Sun Jun 10 2018 12:00:00 ...
chrono.en.parseDate('6/10/2018'); // Sun Jun 10 2018 12:00:00 ...
// UK English or German
chrono.en_GB.parseDate('6/10/2018'); // Sat Oct 06 2018 12:00:00 ...
chrono.de.parseDate('6/10/2018'); // Sat Oct 06 2018 12:00:00 ...
Current supported locale options are: en
, en_GB
, de
, pt
, es
, fr
, ja
Chrono’s extraction pipeline are mainly separated into 'parse' and ‘refine’ phases. During parsing, ‘parsers’ (Parser
) are used to extract patterns from the input text. The parsed results (ParsedResult) are the combined, sorted, then refine using ‘refiners’ (Refiner
). In the refining phase, the results can be combined, filtered-out, or attached with additional information.
Parser is a module for low-level pattern-based parsing. Ideally, each parser should be designed to handle a single specific date format. User can add new type of parsers for supporting new date formats or languages.
var christmasParser = new chrono.Parser();
// Provide search pattern
christmasParser.pattern = function () { return /Christmas/i; };
// This function will be called when matched pattern is found
christmasParser.extract = function(text, ref, match, opt) {
// Return a parsed result, that is 25 December
return new chrono.ParsedResult({
ref: ref,
text: match[0],
index: match.index,
start: {
day: 25,
month: 12,
}
});
};
// Create a new custom Chrono. The initial pipeline 'option' can also be specified as
// - new chrono.Chrono(exports.options.strictOption())
// - new chrono.Chrono(exports.options.casualOption())
var custom = new chrono.Chrono();
custom.parsers.push(christmasParser);
custom.parseDate("I'll arrive at 2.30AM on Christmas night");
// Wed Dec 25 2013 02:30:00 GMT+0900 (JST)
To create a custom parser, override pattern
and extract
methods on an object of class chrono.Parser
.
pattern
method must return RegExp
object of searching pattern.extract
method will be called with the
match object when the pattern is found. This function must create and return a result (or null to skip).Refiner is a higher level module for improving or manipulating the results. User can add a new type of refiner to customize Chrono's results or to add some custom logic to Chrono.
var guessPMRefiner = new chrono.Refiner();
guessPMRefiner.refine = function(text, results, opt) {
// If there is no AM/PM (meridiem) specified,
// let all time between 1:00 - 4:00 be PM (13.00 - 16.00)
results.forEach(function (result) {
if (!result.start.isCertain('meridiem') &&
result.start.get('hour') >= 1 && result.start.get('hour') < 4) {
result.start.assign('meridiem', 1);
result.start.assign('hour', result.start.get('hour') + 12);
}
});
return results;
};
// Create a new custom Chrono. The initial pipeline 'option' can also be specified as
// - new chrono.Chrono(exports.options.strictOption())
// - new chrono.Chrono(exports.options.casualOption())
var custom = new chrono.Chrono();
custom.refiners.push(guessPMRefiner);
// This will be parsed as PM.
// > Tue Dec 16 2014 14:30:00 GMT-0600 (CST)
custom.parseDate("This is at 2.30");
// Unless the 'AM' part is specified
// > Tue Dec 16 2014 02:30:00 GMT-0600 (CST)
custom.parseDate("This is at 2.30 AM");
In the example, a custom refiner is created for assigning PM to parsing results with ambiguous meridiem. The refine
method of the refiner class will be called with parsing results (from parsers or other previous refiners). The method must return an array of the new results (which, in this case, we modified those results in place).
This guide explains how to setup chrono project for prospective contributors.
# Clone and install library
$ git clone https://github.com/wanasit/chrono.git chrono
$ cd chrono
$ npm install
Parsing date from text is complicated. Sometimes, a small change can have effects on unexpected places. So, Chrono is a heavily tested library. Commits that break a test shouldn't be allowed in any condition.
Chrono's unit testing is based-on Jest.
# Run the test
$ npm run test
# Run the test in watch mode
$ npm run watch
Chrono's source files is in src
directory. The built bundle (dist/*
) is created by running Webpack via the following command
$ npm run build
FAQs
A natural language date parser in Javascript
The npm package chrono-node receives a total of 313,698 weekly downloads. As such, chrono-node popularity was classified as popular.
We found that chrono-node demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.